﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;

namespace CommonLibrary
{
    public static class ClString
    {
        /// <summary>
        /// 判断字符串是否为空
        /// </summary>
        /// <param name="in_str"></param>
        /// <returns></returns>
        public static bool ClIsNullOrEmpty(this string in_str)
        {
            return string.IsNullOrEmpty(in_str);
        }

        /// <summary>
        /// 判断字符串是否为空白
        /// </summary>
        /// <param name="in_str"></param>
        /// <returns></returns>
        public static bool ClIsNullOrWhiteSpace(this string in_str)
        {
            if (in_str.ClIsNullOrEmpty())
            {
                return true;
            }

            if (Convert.ToString(in_str).Trim() == "")
            {
                return true;
            }
            return false;
        }

        /// <summary>
        /// 转为字符串，解决Convert.ToString(null)依然为null的问题
        /// </summary>
        /// <param name="in_str"></param>
        /// <returns></returns>
        public static string ClToString(this string in_str)
        {
            if (in_str.ClIsNullOrEmpty())
            {
                return "";
            }

            return Convert.ToString(in_str);
        }

        /// <summary>
        /// 取左边几位
        /// </summary>
        /// <param name="in_str"></param>
        /// <param name="in_int"></param>
        /// <returns></returns>
        public static string ClLeft(this string in_str, int in_int)
        {
            if (in_int < 0) return in_str;
            if (in_int >= in_str.Length) return in_str;

            return in_str.Substring(0, in_int);
        }

        /// <summary>
        /// 取右边几位
        /// </summary>
        /// <param name="in_str"></param>
        /// <param name="in_int"></param>
        /// <returns></returns>
        public static string ClRight(this string in_str, int in_int)
        {
            if (in_int < 0) return in_str;
            if (in_int >= in_str.Length) return in_str;

            return in_str.Substring(in_str.Length - in_int, in_int);
        }

        /// <summary>
        /// 删除右边几位
        /// </summary>
        /// <param name="in_str"></param>
        /// <param name="in_int"></param>
        /// <returns></returns>
        public static string ClRemoveLast(this string in_str, int in_int)
        {
            if (in_int < 0) return in_str;
            if (in_int >= in_str.Length) return "";

            return in_str.Substring(0, in_str.Length - in_int);
        }

        /// <summary>
        /// 拆分字符串
        /// </summary>
        /// <param name="in_str"></param>
        /// <param name="in_split"></param>
        /// <param name="regexOptions"></param>
        /// <returns></returns>
        public static string[] ClSplitString(this string in_str, string in_split, System.Text.RegularExpressions.RegexOptions regexOptions)
        {
            string splitStr = in_split.ClMD5String();
            string str = in_str.Replace(in_split, splitStr);
            string[] arr = System.Text.RegularExpressions.Regex.Split(str, splitStr, regexOptions);

            return arr;
        }

        /// <summary>
        /// 拆分字符串
        /// </summary>
        /// <param name="in_str"></param>
        /// <param name="in_split"></param>
        /// <returns></returns>
        public static string[] ClSplitString(this string in_str, string in_split)
        {
            return in_str.ClSplitString(in_split, System.Text.RegularExpressions.RegexOptions.IgnoreCase);
        }

        /// <summary>
        /// 计算字符串表达式
        /// </summary>
        /// <param name="in_str"></param>
        /// <returns></returns>
        public static object ClEval(this string in_str)
        {
            return new System.Data.DataTable().Compute(in_str, "");
        }


        /// <summary>
        /// 正则表达式IsMatch
        /// </summary>
        /// <param name="s"></param>
        /// <param name="pattern"></param>
        /// <returns></returns>
        public static bool ClIsMatch(this string str, string pattern)
        {
            if (str.ClIsNullOrWhiteSpace())
            {
                return false;
            }

            return Regex.IsMatch(str, pattern);
        }

        /// <summary>
        /// 正则表达式Match
        /// </summary>
        /// <param name="s"></param>
        /// <param name="pattern"></param>
        /// <returns></returns>
        public static string ClMatch(this string str, string pattern)
        {
            if (str.ClIsNullOrWhiteSpace())
            {
                return "";
            }

            return Regex.Match(str, pattern).Value;
        }

        /// <summary>
        /// 正则表达式Match
        /// </summary>
        /// <param name="str"></param>
        /// <param name="pattern"></param>
        /// <returns></returns>
        public static string ClMatch(this string str, string pattern, RegexOptions regexOptions)
        {
            if (str.ClIsNullOrWhiteSpace())
            {
                return "";
            }

            return Regex.Match(str, pattern, regexOptions).Value;
        }

        /// <summary>
        /// 正则表达式Replace
        /// </summary>
        /// <param name="str"></param>
        /// <param name="pattern"></param>
        /// <param name="replaceStr"></param>
        /// <returns></returns>
        public static string ClReplace(this string str, string pattern, string replaceStr)
        {
            if (str.ClIsNullOrWhiteSpace())
            {
                return str;
            }

            return Regex.Replace(str, pattern, replaceStr);
        }

        /// <summary>
        /// 正则表达式Replace
        /// </summary>
        /// <param name="str"></param>
        /// <param name="pattern"></param>
        /// <param name="replaceStr"></param>
        /// <param name="regexOptions"></param>
        /// <returns></returns>
        public static string ClReplace(this string str, string pattern, string replaceStr, RegexOptions regexOptions)
        {
            if (str.ClIsNullOrWhiteSpace())
            {
                return str;
            }

            return Regex.Replace(str, pattern, replaceStr, regexOptions);
        }

        /// <summary>
        /// 正则表达式Replace
        /// </summary>
        /// <param name="str"></param>
        /// <param name="pattern"></param>
        /// <param name="evaluator"></param>
        /// <returns></returns>
        public static string ClReplace(this string str, string pattern, MatchEvaluator evaluator)
        {
            if (str.ClIsNullOrWhiteSpace())
            {
                return str;
            }

            return Regex.Replace(str, pattern, evaluator);
        }

        /// <summary>
        /// 正则表达式Replace
        /// </summary>
        /// <param name="str"></param>
        /// <param name="pattern"></param>
        /// <param name="evaluator"></param>
        /// <param name="regexOptions"></param>
        /// <returns></returns>
        public static string ClReplace(this string str, string pattern, MatchEvaluator evaluator, RegexOptions regexOptions)
        {
            if (str.ClIsNullOrWhiteSpace())
            {
                return str;
            }

            return Regex.Replace(str, pattern, evaluator, regexOptions);
        }

        /// <summary>
        /// 判断文件名是否有特殊字符
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static bool ClIsFileName(this string fileName)
        {
            if (fileName.ClIsNullOrWhiteSpace())
            {
                return false;
            }

            return Regex.Matches(fileName, @"[\\/:*?""<>|]{1,255}").Count > 0 ? false : true;
        }

        /// <summary>
        /// 将文件名含特殊字符的替换为下划线
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static string ClToFileName(this string fileName)
        {
            if (fileName.ClIsNullOrWhiteSpace())
            {
                return "";
            }

            return Regex.Replace(fileName, @"[\\/:*?""<>|]{1,255}", "_");
        }

        /// <summary>
        /// 去空格转大写
        /// </summary>
        /// <param name="in_str"></param>
        /// <returns></returns>
        public static string ClToUpperTrim(this string in_str)
        {
            return in_str.Trim().ToUpper();
        }

        /// <summary>
        /// 将文本字符串转化为字符数组输出
        /// </summary>
        /// <param name="in_str"></param>
        /// <returns></returns>
        private static char[] GetChars(string in_str)
        {
            char[] Cs = in_str.ToCharArray();
            return Cs;
        }

        /// <summary>
        /// 通过字符串创建连接对象
        /// </summary>
        /// <param name="in_ConnectionString"></param>
        /// <returns></returns>
        public static SqlConnection ClToSqlConnection(this string in_ConnectionString)
        {
            SqlConnection cn = new SqlConnection(in_ConnectionString);
            cn.Open();
            return cn;
        }

        /// <summary>
        /// 单引号转全角单引号
        /// </summary>
        /// <param name="in_str"></param>
        /// <returns></returns>
        public static string ClReplaceQuota(this string in_str)
        {
            if (in_str.ClIsNullOrEmpty())
            {
                return in_str;
            }
            return in_str.Replace("'", "’");
        }

        /// <summary>
        /// 下载文件
        /// </summary>
        /// <param name="in_HttpFile"></param>
        /// <param name="in_LocalFile"></param>
        /// <returns></returns>
        public static bool ClDownFileTo(this string in_HttpFile, string in_LocalFile)
        {
            return NetClass.DownFile(in_HttpFile, in_LocalFile);
        }


        /// <summary>
        /// 计算包含汉字字符串的长度
        /// </summary>
        /// <param name="in_str"></param>
        /// <returns></returns>
        public static int ClLengthCn(this string in_str)
        {
            //Regex CnRegex = new Regex("[\u4e00-\u9fa5]+", RegexOptions.Compiled);//汉字
            Regex CnRegex = new Regex("[^\x00-\xff]", RegexOptions.Compiled);//汉字+全角

            Char[] CharArray = in_str.ToCharArray();
            int tmplength = 0;
            for (int i = 0; i < CharArray.Length; i++)
            {
                tmplength += CnRegex.IsMatch(CharArray[i].ToString()) ? 2 : 1;
            }

            return tmplength;
        }

        /// <summary>
        /// 中文取左
        /// </summary>
        /// <param name="in_str"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public static string ClLeftCn(this string in_str, int length, string fill)
        {
            string mFill = fill;
            if (mFill == null)
            {
                mFill = "┅";
            }

            //Regex CnRegex = new Regex("[\u4e00-\u9fa5]+", RegexOptions.Compiled);//汉字
            Regex CnRegex = new Regex("[^\x00-\xff]", RegexOptions.Compiled);//汉字+全角
            Char[] CharArray = in_str.ToCharArray();
            int tmplength = 0;
            for (int i = 0; i < CharArray.Length; i++)
            {
                tmplength += CnRegex.IsMatch(CharArray[i].ToString()) ? 2 : 1;
                if (tmplength > length)
                {
                    return in_str.Substring(0, i - mFill.Length) + mFill;
                }
            }

            return in_str;
        }

        /// <summary>
        /// 中文取左
        /// </summary>
        /// <param name="in_str"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public static string ClLeftCn(this string in_str, int length)
        {
            return in_str.ClLeftCn(length, "");
        }

        /// <summary>
        /// 长文件名转短文件名
        /// </summary>
        /// <param name="longName"></param>
        /// <returns></returns>
        public static string ClShortPathName(this string longName)
        {
            StringBuilder shortNameBuffer = new StringBuilder(256);
            int bufferSize = shortNameBuffer.Capacity;
            int result = SystemHelper.GetShortPathName(longName, shortNameBuffer, bufferSize);
            return shortNameBuffer.ToString();
        }

        /// <summary>
        /// 短文件名转长文件名
        /// </summary>
        /// <param name="shortName"></param>
        /// <returns></returns>
        public static string ClLongPathName(this string shortName)
        {
            StringBuilder longNameBuffer = new StringBuilder(256);
            uint bufferSize = (uint)longNameBuffer.Capacity;
            SystemHelper.GetLongPathName(shortName, longNameBuffer, bufferSize);
            return longNameBuffer.ToString();
        }


        /// <summary>
        /// 拆分规格字符串
        /// </summary>
        /// <param name="in_str">尺码:L/170,M/165;颜色:黄色,宝蓝色,紫色,白色</param>
        /// <returns></returns>
        public static List<Dictionary<string, List<string>>> ClMakeSpecificationList(this string in_str)
        {
            List<Dictionary<string, List<string>>> resultList = new List<Dictionary<string, List<string>>>();

            //可以理解为"售前QQ:1234,2234;售后QQ:6666,7777;查单QQ:6789,9876"

            string[] arrSpecification = in_str.Split(';');
            foreach (string Specification in arrSpecification)
            {
                if (string.IsNullOrEmpty(Specification))
                {
                    continue;
                }

                string[] arrKeyValue = Specification.Trim().Split(':');
                if (arrKeyValue.Length != 2)
                {
                    continue;
                }

                string key = arrKeyValue[0].Trim();

                Dictionary<string, List<string>> keyValueDictionary = new Dictionary<string, List<string>>();

                #region 处理黄色,宝蓝色,紫色,白色

                List<string> valueList = new List<string>();
                string[] arrValue = arrKeyValue[1].Trim().Split(',');
                foreach (string tmpvalue in arrValue)
                {
                    string value = tmpvalue.Trim();
                    if (string.IsNullOrEmpty(value))
                    {
                        continue;
                    }

                    valueList.Add(value);
                }
                #endregion

                keyValueDictionary.Add(key, valueList);

                resultList.Add(keyValueDictionary);
            }

            return resultList;
        }

        /// <summary>
        /// 字符串反转
        /// </summary>
        /// <param name="in_str"></param>
        /// <returns></returns>
        public static string ClReverse(this string in_str)
        {
            char[] arr = in_str.ToCharArray();
            Array.Reverse(arr);
            return new string(arr);
        }

        /// <summary>
        /// UrlEncode
        /// </summary>
        /// <param name="in_str"></param>
        /// <returns></returns>
        public static string ClUrlEncode(this string in_str)
        {
            return HttpUtility.UrlEncode(in_str);
        }

        public static string ClUrlEncode(this string in_str, Encoding encoding)
        {
            return HttpUtility.UrlEncode(in_str, encoding);
        }

        /// <summary>
        /// UrlDecode
        /// </summary>
        /// <param name="in_str"></param>
        /// <returns></returns>
        public static string ClUrlDecode(this string in_str)
        {
            //Request.QueryString会默认做一次HttpUtility.UrlEncode，所有HttpUtility.UrlEncode不要与HttpUtility.UrlDecode对应
            return HttpUtility.UrlDecode(in_str);
        }

        public static string ClUrlDecode(this string in_str, Encoding encoding)
        {
            return HttpUtility.UrlDecode(in_str, encoding);
        }

        /// <summary>
        /// Json的日期转换为字符
        /// </summary>
        /// <param name="in_str"></param>
        /// <returns></returns>
        public static string ClJsonDateToString(this string in_str)
        {
            //"ORDERDATE":"\/Date(1345433307000)\/",---------->"ORDERDATE":"2012-08-20 11:28:27",
            Func<Match, string> ConvertJsonDateToDateString = m =>
            {
                string result = string.Empty;
                DateTime dt = new DateTime(1970, 1, 1);
                dt = dt.AddMilliseconds(long.Parse(m.Groups[1].Value));
                dt = dt.ToLocalTime();
                result = dt.ToString("yyyy-MM-dd HH:mm:ss");
                return result;
            };

            string p = @"\\/Date\((\d+)\)\\/";
            MatchEvaluator matchEvaluator = new MatchEvaluator(ConvertJsonDateToDateString);
            Regex reg = new Regex(p);
            in_str = reg.Replace(in_str, matchEvaluator);

            return in_str;
        }


        public static string ClStringToJsonDate(this string in_str)
        {
            Func<Match, string> ConvertDateStringToJsonDate = m =>
            {
                string result = string.Empty;
                DateTime dt = DateTime.Parse(m.Groups[0].Value);
                dt = dt.ToUniversalTime();
                TimeSpan ts = dt - DateTime.Parse("1970-01-01");
                result = string.Format("\\/Date({0})\\/", ts.TotalMilliseconds);
                return result;
            };

            string p = @"\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}";
            MatchEvaluator matchEvaluator = new MatchEvaluator(ConvertDateStringToJsonDate);
            Regex reg = new Regex(p);
            in_str = reg.Replace(in_str, matchEvaluator);

            return in_str;
        }


        /// <summary>
        /// 写文件
        /// </summary>
        /// <param name="in_file"></param>
        /// <param name="in_msg"></param>
        /// <param name="encoding"></param>
        public static void ClWriteFile(this string in_file, string in_msg, Encoding encoding)
        {
            FileClass.WriteFile(in_file, in_msg, encoding);
        }

        /// <summary>
        /// 写文件
        /// </summary>
        /// <param name="in_file"></param>
        /// <param name="in_msg"></param>
        public static void ClWriteFile(this string in_file, string in_msg)
        {
            FileClass.WriteFile(in_file, in_msg);
        }

        /// <summary>
        /// 读取文件内容
        /// </summary>
        /// <param name="in_file"></param>
        /// <param name="encoding"></param>
        /// <returns></returns>
        public static string ClReadFile(this string in_file, Encoding encoding)
        {
            return FileClass.ReadFile(in_file, encoding);
        }

        /// <summary>
        /// 读取文件内容
        /// </summary>
        /// <param name="in_file"></param>
        /// <returns></returns>
        public static string ClReadFile(this string in_file)
        {
            return in_file.ClReadFile(Encoding.UTF8);
        }


        /// <summary>
        /// 获取配置文件AppSettings的值
        /// </summary>
        /// <param name="in_key"></param>
        /// <returns></returns>
        public static string ClGetConfigAppSettings(this string in_key)
        {
            return System.Configuration.ConfigurationManager.AppSettings[in_key];
        }


        /// <summary>
        /// 将字符串按分隔符转为List
        /// </summary>
        /// <param name="in_str"></param>
        /// <param name="splitString"></param>
        /// <returns></returns>
        public static List<string> ClStringToList(this string in_str, string in_split)
        {
            List<string> listReturn = new List<string>();

            string[] arr = in_str.ClSplitString(in_split ?? ",");
            foreach (string item in arr)
            {
                listReturn.Add(item);
            }

            return listReturn;
        }

        /// <summary>
        /// 将字符串按分隔符转为List
        /// </summary>
        /// <param name="in_str"></param>
        /// <param name="splitString"></param>
        /// <returns></returns>
        public static List<string> ClStringToList(this string in_str)
        {
            return in_str.ClStringToList(",");
        }

        #region string.Format

        /// <summary>
        /// 格式化字符串
        /// </summary>
        /// <param name="in_str"></param>
        /// <param name="arg0"></param>
        /// <returns></returns>
        public static string ClFormat(this string in_str, object arg0)
        {
            return string.Format(in_str, arg0);
        }

        /// <summary>
        /// 格式化字符串
        /// </summary>
        /// <param name="in_str"></param>
        /// <param name="arg0"></param>
        /// <param name="arg1"></param>
        /// <returns></returns>
        public static string ClFormat(this string in_str, object arg0, object arg1)
        {
            return string.Format(in_str, arg0, arg1);
        }

        /// <summary>
        /// 格式化字符串
        /// </summary>
        /// <param name="in_str"></param>
        /// <param name="arg0"></param>
        /// <param name="arg1"></param>
        /// <param name="arg2"></param>
        /// <returns></returns>
        public static string ClFormat(this string in_str, object arg0, object arg1, object arg2)
        {
            return string.Format(in_str, arg0, arg1, arg2);
        }

        /// <summary>
        /// 格式化字符串
        /// </summary>
        /// <param name="in_str"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public static string ClFormat(this string in_str, params object[] args)
        {
            return string.Format(in_str, args);
        }

        /// <summary>
        /// 格式化字符串
        /// </summary>
        /// <param name="in_str"></param>
        /// <param name="provider"></param>
        /// <param name="format"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public static string ClFormat(this string in_str, IFormatProvider provider, string format, params object[] args)
        {
            return string.Format(provider, in_str, args);
        }

        #endregion


        /// <summary>
        /// ToCamel
        /// </summary>
        /// <param name="in_str"></param>
        /// <returns></returns>
        public static string ToCamel(this string in_str)
        {
            if (in_str.ClIsNullOrWhiteSpace()) return in_str;
            return in_str[0].ToString().ToLower() + in_str.Substring(1);
        }

        /// <summary>
        /// ToPascals
        /// </summary>
        /// <param name="in_str"></param>
        /// <returns></returns>
        public static string ToPascal(this string in_str)
        {
            if (in_str.ClIsNullOrWhiteSpace()) return in_str;
            return in_str[0].ToString().ToUpper() + in_str.Substring(1);
        }

        /// <summary>
        /// Parses a string into an Enum
        /// </summary>
        /// <typeparam name="T">The type of the Enum</typeparam>
        /// <param name="value">String value to parse</param>
        /// <returns>The Enum corresponding to the stringExtensions</returns>
        public static T ClToEnum<T>(this string value)
        {
            return ClToEnum<T>(value);
        }


        /// <summary>
        /// 比较第一个字符串开头是否与第二个字符串相同
        /// </summary>
        /// <param name="in_source"></param>
        /// <param name="in_target"></param>
        /// <param name="ignoreCase"></param>
        /// <returns></returns>
        public static bool ClFrontEquals(this string in_source, string in_target, bool ignoreCase)
        {
            string m_source = in_source;
            string m_target = in_target;

            if (m_source == null) throw new ArgumentNullException("源参数不能为空值");
            if (m_target == null) throw new ArgumentNullException("目标参数不能为空值");

            if (m_source.Length < m_target.Length) return false;

            if (ignoreCase)
            {
                m_source = m_source.ToUpper();
                m_target = m_target.ToUpper();
            }

            if (m_source.Substring(0, m_target.Length) != m_target) return false;

            return true;
        }

        /// <summary>
        /// 比较第一个字符串开头是否与第二个字符串相同
        /// </summary>
        /// <param name="in_source"></param>
        /// <param name="in_target"></param>
        /// <returns></returns>
        public static bool ClFrontEquals(this string in_source, string in_target)
        {
            return ClFrontEquals(in_source, in_target, false);
        }

        /// <summary>
        /// 比较第一个字符串开头是否与第二个字符串不相同
        /// </summary>
        /// <param name="in_source"></param>
        /// <param name="in_target"></param>
        /// <param name="ignoreCase"></param>
        /// <returns></returns>
        public static bool ClFrontNotEquals(this string in_source, string in_target, bool ignoreCase)
        {
            return !ClFrontEquals(in_source, in_target, ignoreCase);
        }

        /// <summary>
        /// 比较第一个字符串开头是否与第二个字符串不相同
        /// </summary>
        /// <param name="in_source"></param>
        /// <param name="in_target"></param>
        /// <returns></returns>
        public static bool ClFrontNotEquals(this string in_source, string in_target)
        {
            return !ClFrontEquals(in_source, in_target, false);
        }

    }
}
